package com.ai.ly.goodsautocat.autocat;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.LinkedList;
import java.util.List;

import com.ai.ly.goodsautocat.common.Constants;
import com.ai.ly.goodsautocat.common.SampleFactory;
import com.ai.ly.goodsautocat.common.SampleInfoBuilderFactory;
import com.ai.ly.goodsautocat.util.FileUtil;
import com.ai.ly.goodsautocat.vo.CatInfo;
import com.ai.ly.goodsautocat.vo.PredictSampleVO;

import de.bwaldvogel.liblinear.Feature;
import de.bwaldvogel.liblinear.Model;

public class App {

    public static void main(String[] args) throws Exception {
        // 生成字典
//        SplitSrcWordsToDict.buildDict();
//
//        double testSampleRatio = 0.0;// 测试样本数所占总样本数的比例(大于等于0小于1)
//        trainAndSaveModel(testSampleRatio);

        Model model = AutoCatModelHandler.loadModel();
//        testAllSample(model);

        String gdsName = "华为无线路由器";
        int predict = predict(model, gdsName);
        CatInfo catInfo = CatMap.getCatInfoByIndex(predict);
        if (catInfo==null) {
            System.out.println("无法预测结果");
        }else {
            System.out.println("预测结果：" + gdsName + "=" + catInfo.toString());
        }
        
    }

    public static void testAllSample(Model model) throws Exception {
        System.out.println("使用样本文件中的所有数据进行验证......");
        // 读取样本文件获取所有样本信息-----------------------------------------------------------
        File orgSampleFile = FileUtil.getFileInSys(Constants.orgSampleFilePath);
        List<String> gdsNameList = new LinkedList<>();
        List<Integer> catIndexList = new LinkedList<>();
        List<Integer> pCatIndexList = new LinkedList<>();

        try {
            BufferedReader e = new BufferedReader(new FileReader(orgSampleFile));
            for (String lineContent = e.readLine(); lineContent != null; lineContent = e
                    .readLine()) {
                // 解析每行数据
                int lastIndex = lineContent.lastIndexOf(",");
                if (lastIndex <= 0) {
                    continue;
                }

                String gdsName = lineContent.substring(0, lastIndex);
                // 商品分类
                String catId = lineContent.substring(lastIndex + 1, lineContent.length());
                int catIndex = CatMap.getIndexByCatId(catId);

                gdsNameList.add(gdsName);
                catIndexList.add(catIndex);
            }
            e.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        // 对样本中的数据进行预测
        for (String gdsName : gdsNameList) {
            int predictCatIndex = predict(model, gdsName);
            pCatIndexList.add(predictCatIndex);
        }

        // 验证准确率
        double correctNumber = 0;
        for (int i = 0; i < pCatIndexList.size(); i++) {
            if (pCatIndexList.get(i) == catIndexList.get(i)) {
                correctNumber++;
            }
        }
        double correctRate = correctNumber / pCatIndexList.size();
        System.out.println("对所有样本进行预测，样本数是" + pCatIndexList.size() + "，正确数是" + correctNumber
                + "，准确率是" + correctRate);
    }

    /**
     * 训练模型
     * 
     * @param testSampleRatio
     *            测试样本数所占总样本数的比例(大于等于0小于1)
     * @throws Exception
     */
    public static void trainAndSaveModel(double testSampleRatio) throws Exception {
        AutoCatLibLinearTrainer train = new AutoCatLibLinearTrainer(testSampleRatio);
        // 开始训练
        Model model = train.train();
        // 保存model
        AutoCatModelHandler.saveModel(model);
    }

    /**
     * 使用训练好的模型进行预测
     * 
     * @param gdsName
     *            商品名称
     * @return
     * @throws Exception
     * @author liangyi
     */
    public static int predict(Model model, String gdsName) throws Exception {
        // 根据商品名称生成样本
        PredictSampleVO sample = SampleFactory.buildPredictSample(gdsName,
                SampleInfoBuilderFactory.getBuilderForAutoCat());
        if (sample == null) {
            // System.out.println("这个商品名称不在字典中，不能进行预测...");
            return Integer.MIN_VALUE;
        }

        Feature[] features = FeatureNodeBuilder.buildSvmNodes(sample);
        double predictD = AutoCatPredictor.predictY(model, features);

        int predict = (int) predictD;
        return predict;
    }
}
